package com.lzh.chatnote.chat.service.impl;

import cn.hutool.core.lang.Pair;
import com.lzh.chatnote.chat.dao.GroupMemberDao;
import com.lzh.chatnote.chat.domain.entity.GroupMember;
import com.lzh.chatnote.chat.domain.entity.Room;
import com.lzh.chatnote.chat.domain.entity.RoomGroup;
import com.lzh.chatnote.chat.domain.enums.GroupMemberStatusEnum;
import com.lzh.chatnote.chat.domain.vo.request.group.GroupQueryCursorPageReq;
import com.lzh.chatnote.chat.domain.vo.response.group.GroupQueryResp;
import com.lzh.chatnote.chat.service.GroupMemberService;
import com.lzh.chatnote.chat.service.adapter.GroupMemberAdapter;
import com.lzh.chatnote.chat.service.cache.GroupMemberCache;
import com.lzh.chatnote.chat.service.cache.RoomCache;
import com.lzh.chatnote.chat.service.cache.RoomGroupCache;
import com.lzh.chatnote.chat.utils.ChatMemberHelper;
import com.lzh.chatnote.common.domian.vo.request.CursorPageBaseReq;
import com.lzh.chatnote.common.domian.vo.response.CursorPageBaseResp;
import com.lzh.chatnote.common.utils.AssertUtil;
import com.lzh.chatnote.user.dao.UserDao;
import com.lzh.chatnote.user.domain.entity.User;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class GroupMemberServiceImpl implements GroupMemberService {

    @Resource
    private GroupMemberDao groupMemberDao;
    @Resource
    private RoomCache roomCache;
    @Resource
    private RoomGroupCache roomGroupCache;
    @Resource
    private GroupMemberCache groupMemberCache;
    @Resource
    private UserDao userDao;
    @Override
    public CursorPageBaseResp<GroupQueryResp> queryCursorPage(GroupQueryCursorPageReq groupQueryCursorPageReq) {
        //查询房间
        Room room = roomCache.getOne(groupQueryCursorPageReq.getRoomId());
        AssertUtil.isEmpty(room, "房间不存在");
        List<Long> userIds;
        if (room.isHotRoom()) {
            userIds = null;
        } else {
            //查询房间成员
            RoomGroup roomGroups = roomGroupCache.getOne(room.getId());
            List<GroupMember> groupMembers = groupMemberCache.getOne(roomGroups.getRoomId());
            userIds = groupMembers.stream().map(GroupMember::getUid).collect(Collectors.toList());
        }
        return getMemberPage(userIds, groupQueryCursorPageReq);
    }

    private CursorPageBaseResp<GroupQueryResp> getMemberPage(List<Long> userIds, GroupQueryCursorPageReq req) {
        Pair<GroupMemberStatusEnum, String> cursorPair = ChatMemberHelper.getCursorPair(req.getCursor());
        String cursorValue = cursorPair.getValue();
        //返回结果
        List<GroupQueryResp> resultList = new ArrayList<>(Collections.emptyList());
        Boolean isLast = false;
        GroupMemberStatusEnum nextCursorStatus =  cursorPair.getKey();
        String nextCursorCondition = null;
        //分为两种情况，一种是查询在线成员，一种是查询离线成员,前端用户肯定想要的是优先查询在线成员
        if (cursorPair.getKey() == GroupMemberStatusEnum.ONLINE) {
            //在线成员查询
            CursorPageBaseResp<User> cursorPage = userDao.getCursorPage(userIds, cursorValue, new CursorPageBaseReq(req.getPageSize(), cursorValue), cursorPair.getKey());
            resultList.addAll(GroupMemberAdapter.toGroupResp(cursorPage.getList()));
            //如果不足一页，则继续查询离线成员
            if (cursorPage.getList().size() < req.getPageSize()) {
                //差值页数
                Integer subPage = req.getPageSize() - cursorPage.getList().size();
                CursorPageBaseResp<User> onlineOffPage = userDao.getCursorPage(userIds, cursorValue, new CursorPageBaseReq(subPage, null), GroupMemberStatusEnum.OFFLINE);
                resultList.addAll(GroupMemberAdapter.toGroupResp(onlineOffPage.getList()));
            }
            isLast = cursorPage.getIsLast();
            nextCursorCondition = cursorValue;
        } else if (cursorPair.getKey() == GroupMemberStatusEnum.OFFLINE) {
            //离线成员查询
            CursorPageBaseResp<User> cursorPage = userDao.getCursorPage(userIds, cursorValue, new CursorPageBaseReq(req.getPageSize(), cursorValue), cursorPair.getKey());
            resultList.addAll(GroupMemberAdapter.toGroupResp(cursorPage.getList()));
            isLast = cursorPage.getIsLast();
            nextCursorCondition = cursorValue;
        }
        return new CursorPageBaseResp<>(ChatMemberHelper.mergeCursor(nextCursorStatus, nextCursorCondition), isLast, resultList);
    }
}
